#pragma once

#include <clipper2/clipper.h>
#include <set>

#include <mutex>   // std::mutex
#include <thread>  // std::mutex
#include "qlib/core/error.h"
#include "qlib/core/export.h"
#include "qlib/geo/path.h"
#include "qlib/geo/polygon.h"
#include "qlib/geo/rectangle.h"
#include "qlib/utils/utils.h"

#include "spdlog/spdlog.h"

namespace qlib {

enum struct Operation { Or, And, Xor, Not };
enum struct OffsetJoin { Miter, Bevel, Round };
class QLIB_API ClipperTool {
 public:
  static void boolean(PolygonPtrArray op1, PolygonPtrArray op2, Operation operation, double scaling, PolygonPtrArray& result);

  static void offsetProcessRange(PolygonPtrArray poly, double distance, OffsetJoin join, double tolerance, double scaling, bool use_union,
                                 std::mutex& vectorMutex, std::atomic<int>& threads_remaining, PolygonPtrArray& result);
  static void offsetProcess(const PolygonPtrArray& polygons, double distance, OffsetJoin join, double tolerance, double scaling, bool use_union,
                            PolygonPtrArray& result);
  static void offset(const PolygonPtrArray& polys, double distance, OffsetJoin join, double tolerance, double scaling, bool use_union,
                     PolygonPtrArray& result);

  static void slice(Polygon::s_ptr polygon, const std::vector<double>& positions, bool x_axis, double scaling, std::vector<PolygonPtrArray>& result);

  static void slice(Path::s_ptr path, double posx, double posy, bool x_axis, PathPtrArray& result);

  static void pathIntersectWithRect(Path::s_ptr path, Rectangle::s_ptr _rect, PathPtrArray& result);
};
}  // namespace qlib